#include "maindialog.h"
#include "ui_maindialog.h"
#include "qss.h"

MainDialog::MainDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MainDialog)
{
    ui->setupUi(this);

    initialWidgets();
    initialSignalSlot();

    //窗口关闭后自动调用析构，不加不会调用
    setAttribute(Qt::WA_DeleteOnClose);
}

MainDialog::~MainDialog()
{
    // 关闭串口
    if(serialPort != nullptr)
    {
        if(serialPort->isOpen())
        {
            serialPort->close();
        }
    }
    delete ui;
}


/**
 * @brief MainDialog::setQssStyle
 * 初始化各种组件
 */
void MainDialog::initialWidgets()
{
    for(int i = 0;i < ui->listWidget->count();i++)
    {
        ui->listWidget->item(i)->setSizeHint(QSize(0, 80));
    }
    ui->listWidget->setStyleSheet(QListWidget_STYTLE);
    ui->pushButtonConn->setStyleSheet(QPushButton_STYTLE);
    ui->slider_reset->setStyleSheet(QSlider_STYTLE);
    ui->slider_action1->setStyleSheet(QSlider_STYTLE);
    ui->slider_action2->setStyleSheet(QSlider_STYTLE);
    ui->slider_action3->setStyleSheet(QSlider_STYTLE);

    connectBtnGroup = new QButtonGroup(this);

    // 复原上次输入
    QSettings setting("config.ini",QSettings::IniFormat);
    setting.setIniCodec(QTextCodec::codecForName("UTF-8"));

    setting.beginReadArray("MainDialog");
    QString ip = setting.value("server ip").toString();
    QString port = setting.value("server port").toString();

    ip = setting.value("haas ip").toString();
    port = setting.value("haas port").toString();
    setting.endArray();

    // 不连接就不给进入控制和接收的page
    ui->page_control->setEnabled(false);

    progressDialog = new QProgressDialog("串口正在连接中...", "取消连接", 0, 100, this);
    progressDialog->setWindowModality(Qt::WindowModal);
    progressDialog->setWindowTitle("连接中...");
    progressDialog->setCancelButton(NULL);
    progressDialog->setValue(0);
    progressDialog->resize(500,150);
    progressDialog->close();
    progressDialog->installEventFilter(this);
    progressDialog->setWindowFlags((windowFlags() & ~Qt::WindowCloseButtonHint));

    sliderDialog = new QProgressDialog("命令发送执行中，请稍等...","",0,100,this);
    sliderDialog->setWindowModality(Qt::WindowModal);
    sliderDialog->setWindowTitle("执行中...");
    sliderDialog->setCancelButton(NULL);
    sliderDialog->setValue(0);
    sliderDialog->resize(500,150);
    sliderDialog->close();
    sliderDialog->installEventFilter(this);
    sliderDialog->setWindowFlags((windowFlags() & ~Qt::WindowCloseButtonHint));
}

/**
 * @brief MainDialog::initialSignalSlot
 * 初始化信号槽
 */
void MainDialog::initialSignalSlot()
{
    connect(ui->listWidget, SIGNAL(currentRowChanged(int)),
            ui->stackedWidget, SLOT(setCurrentIndex(int)));
    connect(ui->pushButtonConn,SIGNAL(clicked()),
            this,SLOT(btnConnClickedSlot()));
    connect(ui->slider_reset,SIGNAL(valueChanged(int)),
            this,SLOT(sliderValueChanged(int)));
    connect(ui->slider_action2,SIGNAL(valueChanged(int)),
            this,SLOT(sliderValueChanged(int)));
    connect(ui->slider_action3,SIGNAL(valueChanged(int)),
            this,SLOT(sliderValueChanged(int)));
    connect(ui->slider_action1,SIGNAL(valueChanged(int)),
            this,SLOT(sliderValueChanged(int)));
}

/**
 * @brief MainDialog::showMessage 方便弹出QMessageBox
 * @param type 1:question 2:infortion 3:warning 4:critical
 * @param msg 信息内容
 */
void MainDialog::showMessage(QString msg,MessageType type = MessageType::WARNING)
{
    QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    time.append("\n");
    if(type == MessageType::QUESTION)
    {
        QMessageBox::question(this,this->windowTitle(),msg.prepend(time));
    }else if(type == MessageType::INFORMATION)
    {
        QMessageBox::information(this,this->windowTitle(),msg.prepend(time));
    }else if(type == MessageType::WARNING)
    {
        QMessageBox::warning(this,this->windowTitle(),msg.prepend(time));
    }else if(type == MessageType::CRITICAL)
    {
        QMessageBox::critical(this,this->windowTitle(),msg.prepend(time));
    }
}

/**
 * @brief MainDialog::connect2SerialPort
 * 串口连接函数
 */
bool MainDialog::connect2SerialPort()
{
    int com = ui->spinBoxCom->value();
    int baudRate = ui->spinBoxBaud->value();
    QString strCom = "com";
    strCom.append(QString::number(com));

    serialPort = new QSerialPort(this); // 串口连接代码
    serialPort->setPortName(strCom); // 设置串口名称
    serialPort->setBaudRate(baudRate); // 设置波特率
    serialPort->setDataBits(QSerialPort::Data8); // 设置数据位
    serialPort->setParity(QSerialPort::NoParity); // 设置校验位
    serialPort->setStopBits(QSerialPort::OneStop); // 设置停止位
    serialPort->setFlowControl(QSerialPort::NoFlowControl); // 设置流控制

    // 连接串口
    return serialPort->open(QIODevice::ReadWrite);
}

bool MainDialog::sendSerialCmd(MainDialog::CommandType cmd)
{
    QByteArray data;
    if(cmd == CommandType::RESET)
    {
        // 发送复位命令
        data = "0";
    }
    else if(cmd == CommandType::ACTION1)
    {
        // 发送动作1命令
        data = "1";
    }
    else if(cmd == CommandType::ACTION2)
    {
        // 发送动作2命令
        data = "2";
    }
    else if(cmd == CommandType::ACTION3)
    {
        // 发送动作3命令
        data = "3";
    }
    else
    {
        showMessage("没有此命令",WARNING);
        return false;
    }

    int wirteRet = serialPort->write(data); // 发送命令
    if(wirteRet == -1)
    {
        return false;
    }
    return true;
}

bool MainDialog::eventFilter(QObject *obj, QEvent *event)
{
    if(obj==sliderDialog && event->type() == QEvent::Close)
    {
        qDebug() << "sliderDialog close";
        ui->slider_action1->setValue(0);
        ui->slider_action2->setValue(0);
        ui->slider_action3->setValue(0);
        ui->slider_reset->setValue(0);
    }
    return QDialog::eventFilter(obj,event);
}

void MainDialog::btnConnClickedSlot()
{
    if(ui->pushButtonConn->text() == "已连接")
    {
        ui->pushButtonConn->setText("连接");
        if(serialPort->isOpen())
        {
            serialPort->close();
            qDebug() << "串口连接断开";
        }
        ui->page_control->setEnabled(false);
        showMessage("串口连接已断开!",INFORMATION);
        return;
    }
    // 初始化并连接串口
    bool connectRet = connect2SerialPort();
    if(connectRet)
    {
        // 串口连接进度
        if(timerConnect == NULL)
        {
            timerConnect = new QTimer;
            timerConnect->setInterval(10); // 根据实际连接时间调节，多给点时间，因为机械臂不给连接成功的反馈
            timerConnect->setSingleShot(false);
            connect(timerConnect,SIGNAL(timeout()),this,SLOT(connTimeoutSlot()));
            progressDialog->show();
        }
        else
        {
            progressDialog->show();
        }
    }
    else
    {
        showMessage("串口连接失败!",CRITICAL);
        return;
    }
    timerConnect->start();
}

void MainDialog::connTimeoutSlot()
{
    progressDialog->setValue(progress);
    if(progress == 100)
    {
        progressDialog->close();
    }
    progress++;
    if(progress > 100)
    {
        progress = 0;
        timerConnect->stop();
//        ui->pushButtonConn->setEnabled(false);
        ui->pushButtonConn->setText("已连接");
        ui->listWidget->setCurrentRow(1);
        ui->page_control->setEnabled(true);
    }
}

void MainDialog::cmdTimeoutSlot()
{
    sliderDialog->setValue(progress);
    if(progress == 0)
        sliderDialog->setLabelText("命令发送执行中，请稍等...");
    else if(progress == 70)
        sliderDialog->setLabelText("在坚持等待一会...");
    else if(progress == 90)
    {
        timerCmd->setInterval(10);
        sliderDialog->setLabelText("命令发送完毕！");
    }
    else if(progress == 100)
        sliderDialog->close();
    progress++;
    if(progress > 100)
    {
        progress = 0;
        timerCmd->stop();
        if(sendRet)
        {
            showMessage("命令发送成功!",INFORMATION);
        }
        else if(sendRet == false)
        {
            showMessage("命令发送失败!",CRITICAL);
        }
    }
}

void MainDialog::sliderValueChanged(int value)
{
    if(value == 0)
    {
        return;
    }

    if(sender() == ui->slider_reset)
    {
        sendRet = sendSerialCmd(CommandType::RESET);
    }
    else if(sender() == ui->slider_action1)
    {
        sendRet = sendSerialCmd(CommandType::ACTION1);
    }
    else if(sender() == ui->slider_action2)
    {
        sendRet = sendSerialCmd(CommandType::ACTION2);
    }
    else if(sender() == ui->slider_action3)
    {
        sendRet = sendSerialCmd(CommandType::ACTION3);
    }
    else
    {
        sendRet = false;
    }

    // 串口命令发送进度
    if(timerCmd == NULL)
    {
        timerCmd = new QTimer;
        timerCmd->setSingleShot(false);
        connect(timerCmd,SIGNAL(timeout()),this,SLOT(cmdTimeoutSlot()));
        sliderDialog->show();
    }
    else
    {
        sliderDialog->show();
    }
    timerCmd->setInterval(50); // 给机械臂5s的执行时间
    timerCmd->start();
}


